package com.itheima.stock.sharding;

import com.google.common.collect.Range;
import org.apache.shardingsphere.api.sharding.ShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;
import org.joda.time.DateTime;

import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 *  数据库分库策略算法
 */
public class CommonShardingAlgorithm4Db implements PreciseShardingAlgorithm<Date>, RangeShardingAlgorithm<Date> {
    @Override
    public String doSharding(Collection<String> dsNames, PreciseShardingValue<Date> preciseShardingValue) {
        //1.获取分片键的值
        Date time = preciseShardingValue.getValue();
        //2.获取年份
        int year = new DateTime(time).getYear();
        //3.过滤出需要查询的数据库
        Optional<String> database = dsNames.stream().filter(db -> db.endsWith(year + "")).findFirst();
        //4.1数据库存在 返回查询到了的
        if (database.isPresent()){
            return database.get();
        }
        //4.2不存在即返回空
        return null;
    }

    @Override
    public Collection<String> doSharding(Collection<String> dsNames, RangeShardingValue<Date> rangeShardingValue) {
        //1.获取分片键的值
        Range<Date> valueRange = rangeShardingValue.getValueRange();
        //2.获取年份下限
        if (valueRange.hasLowerBound()){
            Date lowerTime = valueRange.lowerEndpoint();
            int lowerYear = new DateTime(lowerTime).getYear();
            //2.1过滤出需要查询的数据库
            dsNames = dsNames.stream().filter(db -> {
                int i = Integer.parseInt(db.split("-")[1]);
                return i >= lowerYear;
            }).collect(Collectors.toList());
        }
        //3.获取年份上限
        if (valueRange.hasUpperBound()) {
            Date upperTime = valueRange.upperEndpoint();
            int upperYear = new DateTime(upperTime).getYear();
            //3.1过滤出需要查询的数据库
            dsNames = dsNames.stream().filter(db -> {
                int i = Integer.parseInt(db.split("-")[1]);
                return i <= upperYear;
            }).collect(Collectors.toList());
        }

        //4.返回所需要的数据库名称
        return dsNames;
    }
}
